package com.tools.elk;

import org.apache.http.HttpHost;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;

import javax.naming.directory.SearchResult;
import java.io.IOException;

public class SelectES {
    public static void main(String[] args) throws IOException {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200,"http"))
        );
        //单个
//        GetRequest getRequest = new GetRequest();
//        getRequest.index("user").id("1000");
//        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
//        System.out.println(response.getSourceAsString());
        //条件查询
        SearchRequest searchRequest = new SearchRequest();

//        1,全量查询
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        2.精准查询
//        term做精确查询可以用它来处理数字，布尔值，日期以及文本。查询数字时问题不大，但是当查询字符串时会有问题。
//        term查询的含义是termQuery会去倒排索引中寻找确切的term,但是它并不知道分词器的存在。
//        term表示查询字段里含有某个关键词的文档，terms表示查询字段里含有多个关键词的文档。
//        也就是说直接对字段进行term本质上还是模糊查询，只不过不会对搜索的输入字符串进行分词处理罢了。
//        如果想通过term查到数据，那么term查询的字段在索引库中就必须有与term查询条件相同的索引词，否则无法查询到结果。
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.termQuery("name.keyword", "洞拐洞拐"));
        //或者
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchPhraseQuery("name", "洞拐洞拐"));
//        3.组合条件查询
 /*       SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(QueryBuilders.boolQuery()
//                .must(QueryBuilders.matchQuery("name", "王常风"))
//                .must(QueryBuilders.matchQuery("age", 32))
//                .mustNot(QueryBuilders.matchQuery("sex", "女"))
                .should(QueryBuilders.matchQuery("name", "洞拐洞拐"))//或者
        );*/
//        4.范围查询
     /*   SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(
                QueryBuilders.rangeQuery("age").gte(30)
        );*/
        //模糊查询
        /*    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(
                QueryBuilders.fuzzyQuery("name","大")
                        .fuzziness(Fuzziness.TWO) //代表错两个个字符也可以查询
        );*/

        //高亮显示
//        sourceBuilder.highlighter(new HighlightBuilder().preTags("red").postTags("/red").field("name"));
        //聚合查询
//        sourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));
        //分组查询
        sourceBuilder.aggregation(AggregationBuilders.terms("AgeGroup").field("age"));
//        2, 且分页，且排序
//        sourceBuilder .from(0).size(4).sort("age", SortOrder.ASC);
        //排除/包含字段
//        sourceBuilder.fetchSource(new String[]{"name"}, new String[]{"age"});

        searchRequest.indices("user").source(sourceBuilder);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println(search.getTook());
        for(SearchHit searchHit:hits){
            System.out.println(searchHit.getSourceAsString());
        }
        client.close();


    }
}
